Occasionally-binding constraints ================================= An *occasionally-binding constraint* (OBC) is an inequality on a model variable that holds with equality only some of the time -- the zero (or effective) lower bound on the policy rate, irreversible investment, a collateral constraint, a capacity limit, the irreversibility-of-capital constraint, and so on. OBCs come in **two complementary forms** in RISE, and the rest of this chapter is organized around that distinction: 1. **The traditional form: kinky functions in the model equations.** Use ``min``, ``max``, ``abs``, ... directly in the right-hand side of the equation that pins the constrained variable. The solver's treatment of these kinky functions then depends on the context: * In a **deterministic** context (perfect-foresight / extended path), the kinky functions are enforced *exactly* -- the nonlinear deterministic solver treats ``max(0, R*)`` as the true mathematical operation. * In a **stochastic** context (perturbation around a steady state), the kinky functions cannot be enforced exactly in a single linear solution; they are treated *slightly differently* -- the perturbation engine smooths or splits them across regimes, using one of the routes documented below. 2. **The complementary form: regime-switching approximation.** The OBC is approximated by a two-state Markov chain (slack regime / binding regime) with the transitions driven by whether the constraint binds. The switching-model solver then handles the problem with the standard regime-switching machinery. The two forms are not mutually exclusive. A model file with a ``max(0, ...)`` kink can be solved deterministically (exact) or under one of the stochastic-context treatments (approximate); alternatively, the same constraint can be recast as a ``bind`` Markov chain and solved via the regime-switching route. .. note:: **The occbin algorithm is a paradigm.** The piecewise-linear OccBin algorithm lives in the paradigm framework as ``occbin.paradigm`` (see :doc:`/WorkingWithAModel/Extending RISE through paradigms`), not in mainland RISE. OBC itself is *not* a paradigm: the deterministic (perfect-foresight) and anticipated-shocks routes are ordinary RISE features. This chapter covers the OBC modeling; the piecewise-linear solve is delegated to the OccBin paradigm. .. contents:: :local: :depth: 2 Form 1. Kinky functions ------------------------ Declaration ~~~~~~~~~~~~ Write the inequality as a ``max``, ``min`` or ``abs`` on the right-hand side of the equation that pins the constrained variable:: @endogenous PAI Y R RSTAR @model RSTAR = rss + phi_pi*PAI; % shadow Taylor rule R = max(0, RSTAR); % zero lower bound on R The parser recognizes the kink at parse time. The same model file is used by the deterministic solver and by the stochastic-context routes; no additional declaration is required. Deterministic context: exact enforcement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For perfect-foresight / extended-path simulations -- where the model is solved as a deterministic two-point boundary problem over a finite horizon -- the kinky functions are enforced *exactly*. ``max(0, RSTAR)`` is the literal mathematical operation the deterministic nonlinear solver applies at each period of the horizon. This is the route to use for scenarios where the constraint genuinely binds for known stretches of time and the deterministic treatment is appropriate (a known-and-announced rate path, a scheduled fiscal consolidation, etc.). See :doc:`Deterministic and quasi-deterministic solutions`. Stochastic context: approximate treatments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In a stochastic context the kinky functions cannot be enforced exactly within a single linear (or higher-order) perturbation solution. The solver picks one of the approximate treatments: * **Anticipated-shock smoothing.** The solver adds one *fudge shock* per kink-equation (named ``FUDGE_FACTOR_n``) whose announced future values hold the constrained variable on the admissible side at each iteration. The option ``solve_shock_horizon`` controls how far ahead the fudge shocks are anticipated; the cell-array form sets it per fudge shock for multi-constraint models. * **Piecewise-linear (OccBin) approximation.** Provided by the ``occbin.paradigm`` solve paradigm -- a self-contained piecewise-linear solver that iterates on *when* the constraint binds across the horizon. See :doc:`/WorkingWithAModel/Extending RISE through paradigms`. These are not exact; they are *approximations* of the kinky constraint inside a stochastic perturbation solver. The choice of treatment is a solve-time option, not a model-file declaration. Form 2. Regime-switching approximation --------------------------------------- The complementary form recasts the OBC as a two-state Markov chain whose ``bind`` parameter is ``0`` in the slack regime and ``1`` in the binding regime, and writes the constrained equation as the convex combination of the slack and binding cases:: @parameters(zlb, 2, "slack", "bound") bind @parameters zlb_tp_1_2 zlb_tp_2_1 i_floor @model i_taylor = phi_pi*pi + phi_y*x; i = bind*i_floor + (1-bind)*i_taylor; The constraint is now a chain like any other -- except that the switching is *endogenous* (driven by whether the constraint binds), not stochastic. Solving with the OccBin paradigm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The piecewise-linear solve of this construction is provided by the ``occbin.paradigm`` solve paradigm. Activate it at solve time, naming the reference (slack) regime and listing the constraints:: C = { struct('var','R','dir',-1,'bound',1,'chain','ocb') }; % R >= 1 m = set(m,'solve_paradigm',{@occbin.paradigm,'ref',1,'constraints',C}); m = solve(m); sims = simulate(m,'simul_periods',1000); Here ``ref`` is the integer ID of the reference composite regime, and each constraint struct gives the bounded variable, the violation direction (``-1`` for ``var >= bound``, ``+1`` for ``var <= bound``), the bound and the switching chain. The paradigm enforces the constraint at simulation time and scales to any number of chains. It also imposes a single common steady state and pins the constraint chains' transition probabilities to zero itself, so you need not pass ``sstate_imposed`` / ``sstate_unique`` or zero those probabilities in the calibration. The constraint-cell grammar and the remaining options (``maxspell``, ``use_pinv``) are documented with the paradigm in :doc:`/WorkingWithAModel/Extending RISE through paradigms`. Side constraints inside an optimization problem ------------------------------------------------ A different but related construction: a planner's optimization problem with a *side constraint* (a ``\geq`` / ``\leq`` restriction the planner must honor). The constraint enters through the ``@constraint`` option of an ``@optimization_problem`` block:: @optimization_problem{ @discount = beta, @objective = -0.5*(pi^2 + lambda_y*y^2), @constraint = gam : i >= i_floor; } The regime indicator ``gam`` is a switching parameter that equals ``1`` when the constraint binds and ``0`` when slack. RISE attaches a Lagrange multiplier and writes the complementary-slackness condition automatically. See :doc:`Optimal policy` for the full ``@optimization_problem`` grammar. This is the planner-with-constraint case; it is technically an OBC construction but the analysis discipline is different (the side constraint is part of the policy problem, not a private-sector behavioral equation). Use it when the constraint is a feature of the *planner's choice set*; use Form 1 or Form 2 when the constraint is a feature of the *equilibrium*. Simulation and IRFs under OBC ------------------------------ Once the constrained model is solved, ``simulate``, ``irf``, ``forecast`` and ``filter`` respect the constraint with the chosen algorithm. Two pieces of guidance: * **Use generalized IRFs.** With an OBC the model is genuinely nonlinear, so the meaningful impulse response averages over the state distribution. Run ``irf(m, irf_type = 'girf', irf_draws = 1000)`` instead of the simple IRF that traces the response from a fixed point. * **Watch how often the bound binds.** A simulation that spends 100% of periods at the bound (or 0%) is a sign of a calibration outside the determinacy region for the chosen route, not necessarily of a bug. Check the unconstrained-rate distribution against the floor. Where to look next ------------------- * :doc:`Deterministic and quasi-deterministic solutions` -- the deterministic context in full; this is where Form 1 delivers exact enforcement. * :doc:`/WorkingWithAModel/Extending RISE through paradigms` -- the ``occbin.paradigm`` engine that performs the piecewise-linear solve of the regime-switching construction. * :doc:`Optimal policy` -- the ``@optimization_problem`` grammar, including ``@constraint``.